import random
from app.user import user
from flask import render_template, request, jsonify, session, flash, redirect, url_for
from sqlalchemy import desc, asc
from app.utils.models import User, Book, Comment, Item
from app.app import db
from pyecharts.charts import Bar, Pie, Line
from pyecharts import options as opts
from pyecharts.globals import ThemeType


@user.route("/")
def index():
    # chart0 = get_chart0().render_embed()
    chart1 = get_chart1().render_embed()
    chart2 = get_chart2().render_embed()
    if session.get('user_id'):
        user_id = session.get('user_id')
        user = User.query.get(user_id)
    else:
        user = None
    books = Book.query.all()
    integers = [random.randint(0, len(books) - 1) for _ in range(5)]
    random_book = []
    for i in integers:
        random_book.append(books[i])
    sort_books = sorted(books, key=lambda book: book.top, reverse=True)
    return render_template("user/home.html", random_book=random_book, books=sort_books, user=user,
                           chart1=chart1, chart2=chart2)


@user.route("/car")
def car():
    user_id = session.get('user_id')
    user = User.query.get(user_id)
    items = Item.query.filter_by(user_id=user_id, is_pay=0, is_cancel=0).all()
    book_item = []
    for item in items:
        book = Book.query.filter_by(book_id=item.book_id).first()
        book_item.append({**book.__dict__, **item.__dict__})
    return render_template("user/car.html", items=book_item, user=user)


@user.route("/orders")
def orders():
    user_id = session.get('user_id')
    user = User.query.get(user_id)
    items = Item.query.filter_by(user_id=user_id).all()
    book_item = []
    for item in items:
        book = Book.query.filter_by(book_id=item.book_id).first()
        book_item.append({**book.__dict__, **item.__dict__})
    book_item = sorted(book_item, key=lambda x: x['is_pay'])
    book_item = sorted(book_item, key=lambda x: x['is_cancel'])
    return render_template("user/order.html", items=book_item, user=user)


@user.route("/login", methods=["GET", "POST"])
def login():
    if request.method == "POST":
        name = request.form["username"]
        password = request.form["password"]
        result = User.query.filter(User.name == name).first()
        if result is not None and result.password == password:
            if result.admin == 0:
                session['user_id'] = result.id
                return redirect(url_for('user.index'))
            else:
                session['admin_id'] = result.id
                return redirect(url_for('admin.index'))

        else:
            flash('用户名或密码错误，请重试。', 'error')
            return redirect(url_for('user.login'))
    else:
        return render_template("user/login.html")


@user.route("/register", methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        name = request.form['username']
        password = request.form['password']
        result = User.query.filter(User.name == name).first()
        if len(password) < 4:
            flash('注册失败，密码必须大于4位')
            return redirect(url_for('user.register'))
        if result:
            flash('用户已注册！', 'error')
            return redirect(url_for('user.register'))
        else:
            new_user = User(name=name, password=password)
            db.session.add(new_user)
            db.session.commit()
            flash('注册成功！请登录！', 'success')
            return redirect(url_for('user.login'))
    else:
        return render_template("user/register.html")


@user.route('/detail/<int:book_id>')
def detail(book_id):
    book = Book.query.get(book_id)
    user_id = session.get('user_id')
    user = User.query.get(user_id)
    # count = Comment.query.filter_by(book_id=book_id).count()
    comments = Comment.query.filter_by(book_id=book_id)
    commentss=[]
    for comment in comments:
        user_name=User.query.get(comment.user_id).name
        comment = {
            'comment': comment.to_dict(),
            'name': user_name
        }
        commentss.append(comment)
    return render_template('user/detail.html', book=book, comment_count=comments.count(), comments=commentss, user=user)


@user.route('/add_to_car', methods=['POST'])
def add_to_car():
    if request.method == 'POST':
        if session.get('user_id'):
            book_id = request.form['book_id']
            number = request.form['number']
            user_id = session.get('user_id')
            item = Item(book_id=book_id, number=number, user_id=user_id)
            db.session.add(item)
            try:
                db.session.commit()
                return jsonify({'message': '书籍已添加到购物车', 'item_id': item.item_id}), 201
            except Exception as e:
                db.session.rollback()
                return jsonify({'error': str(e)}), 500
        else:
            return jsonify({'message': '请先登录'}), 201
    return '无效的请求方法', 405


@user.route('/add_comment', methods=['POST'])
def add_comment():
    if request.method == 'POST':
        if session.get('user_id'):
            user_id = session.get('user_id')
            comment = request.form['comment']
            book_id = request.form['book_id']
            print(user_id, comment, book_id)
            comment = Comment(book_id=book_id, user_id=user_id, comment=str(comment))
            db.session.add(comment)
            db.session.commit()
            return jsonify({'message': '评论成功', 'book_id': book_id}), 201
        else:
            return jsonify({'message': '系统出错'}), 401
    return jsonify({'message': '系统出错'}), 401


@user.route('/pay', methods=['POST'])
def pay():
    if request.method == 'POST':
        if session.get('user_id'):
            book_id = request.form['book_id2']
            number = request.form['number2']
            user_id = session.get('user_id')
            item = Item(book_id=book_id, number=number, user_id=user_id, is_pay=1)
            book = Book.query.filter_by(book_id=book_id).first()
            book.top += int(item.number)
            db.session.add(book)
            db.session.add(item)
            # 提交会话以保存更改
            try:
                db.session.commit()
                return jsonify({'message': '购买成功', 'book': book.to_dict()}), 201
            except Exception as e:
                db.session.rollback()
                return jsonify({'error': str(e)})
        else:
            return jsonify({'message': '请先登录'}), 201
    return '无效的请求方法', 405


@user.route('/delete/<int:item_id>', methods=['DELETE'])
def delete(item_id):
    item = Item.query.get(item_id)
    print(request.method)
    print(item)
    if request.method == 'DELETE':
        db.session.delete(item)
        if item:
            db.session.commit()
            return jsonify({'message': '移除成功', 'item_id': item_id})
        else:
            return jsonify({'message': '系统错误', 'item_id': item_id})


@user.route('/delete_car/<int:item_id>', methods=['POST'])
def delete_car(item_id):
    item = Item.query.get(item_id)
    print(request.method)
    print(item)
    if request.method == 'POST':
        print("取消订单")
        if item:
            item.is_cancel = 1
            db.session.commit()
            return jsonify({'message': '移除成功', 'item_id': item_id}), 201
        else:
            return jsonify({'message': '系统错误', 'item_id': item_id}), 401


@user.route('/pay_car/<int:item_id>', methods=['POST'])
def pay_car(item_id):
    item = Item.query.get(item_id)
    book = Book.query.filter_by(book_id=item.book_id).first()
    if request.method == 'POST':
        if item:
            item.is_pay = 1
            db.session.commit()
            return jsonify({'message': '支付成功', 'book': book.to_dict()}), 201
        else:
            return jsonify({'message': '支付失败', 'item_id': item_id}), 401


@user.route('/search', methods=['GET'])
def search():
    user_id = session.get('user_id')
    user = User.query.get(user_id)
    key = request.args.get('keyword')  # 从查询字符串中获取 'key'
    books = Book.query.filter(Book.book_name.contains(key)).all()
    return render_template("user/search.html", books=books, user=user)


@user.route('/about', methods=['GET'])
def about():
    page = int(request.args.get("page", 1))

    chart3 = get_chart3(page).render_embed()
    chart4 = get_chart4(page).render_embed()
    # p = Book.query.paginate(page=page, per_page=per_page)
    page = request.args.get('page', 1, type=int)
    page_book = Book.query.paginate(page=page, per_page=8)
    if session.get('user_id'):
        user_id = session.get('user_id')
        user = User.query.get(user_id)
        return render_template('user/about.html', user=user, books=page_book, page=page_book, p=page_book,
                               chart3=chart3, chart4=chart4)
    else:
        return render_template('user/about.html', books=page_book, page=page_book, p=page_book, chart3=chart3,
                               chart4=chart4)


@user.route('/logout', methods=['GET'])
def logout():
    session.clear()
    return jsonify({'message': '退出成功'}), 201


@user.route('/hot_map',methods=['GET'])
def hot_map():
    return render_template('user/air_quality_baidu_map.html')


# 全局图，销量前n个图书
def get_chart0():
    books = Book.query.order_by(desc('top')).limit(8)
    x_data = []
    y_data = []
    for book in books:
        x_data.append(book.book_name)
        y_data.append(book.top)
    bar = (
        Bar(init_opts=opts.InitOpts(width='400px', height='400px', theme=ThemeType.DARK))
        .add_xaxis(x_data)  # 添加x轴数据
        .add_yaxis("销售量", y_data, )  # 添加男生数量序列，设置堆叠为'总量'  # 添加女生数量序列，同样设置堆叠为'总量'
        .set_global_opts(
            title_opts=opts.TitleOpts(title="销售榜前8"),  # 设置图表标题
            yaxis_opts=opts.AxisOpts(name="图书"),  # 设置y轴名称
            toolbox_opts=opts.ToolboxOpts(  # 工具箱配置项
                is_show=True,  # 是否显示工具箱
                feature={
                    "saveAsImage": {},  # 保存为图片
                    "magicType": {  # 数据视图切换，保持默认配置即支持折线图和柱状图
                        "type": ["bar", "line"],
                        "title": {"line": "折线图", "bar": "柱状图"},
                    },
                },
            ),
        )
    )
    return bar


# 全局图-全部出版社出版图书数量
def get_chart1():
    books = Book.query.filter()
    x_data = []
    y_data = []
    publisher_count = {}
    for book in books:
        if book.derive not in publisher_count:
            publisher_count[book.derive] = 1
        else:
            publisher_count[book.derive] += 1
    for key, value in publisher_count.items():
        x_data.append(key)
        y_data.append(value)
    bar = (
        Line(init_opts=opts.InitOpts(width='400px', height='500px', theme=ThemeType.LIGHT))
        .add_xaxis(x_data)  # 添加x轴数据
        .add_yaxis("出版数量", y_data, )  # 添加男生数量序列，设置堆叠为'总量'  # 添加女生数量序列，同样设置堆叠为'总量'
        .set_global_opts(
            title_opts=opts.TitleOpts(title="总出版数"),  # 设置图表标题
            yaxis_opts=opts.AxisOpts(name="数量"),  # 设置y轴名称
            datazoom_opts=[opts.DataZoomOpts(type_="slider", is_realtime=True)],
            toolbox_opts=opts.ToolboxOpts(  # 工具箱配置项
                is_show=True,  # 是否显示工具箱
                feature={
                    "saveAsImage": {},  # 保存为图片
                    "magicType": {  # 数据视图切换，保持默认配置即支持折线图和柱状图
                        "type": ["bar", "line"],
                        "title": {"line": "折线图", "bar": "柱状图"},
                    },
                },
            ),
        )
    )
    return bar


# 全局图-全部图书的价格分布图
def get_chart2():
    books = Book.query.filter()
    prices = []
    y_data = []
    a, b, c, d, e, = 0, 0, 0, 0, 0
    x_data = ["0-30元", "31-60元", "61-100元", "101-200元", "201-500元"]
    for book in books:
        prices.append(float(book.price))
    for price in prices:
        if 0 <= price <= 30:
            a = a + 1
        elif 31 <= price <= 60:
            b = b + 1
        elif 61 <= price <= 100:
            c = c + 1
        elif 101 <= price <= 200:
            d = d + 1
        else:
            e = e + 1
    y_data.extend([a, b, c, d, e])
    pie = Pie(init_opts=opts.InitOpts(width='500px', height='500px', theme=ThemeType.LIGHT)).set_global_opts(
        title_opts=opts.TitleOpts(title="全部图书价格分布"),
        legend_opts=opts.LegendOpts(pos_left="70%", orient='vertical')  # 设置图表标题
    )
    pie.add(' ', [list(x) for x in zip(x_data, y_data)])
    return pie


# 局部图-每个页面的图书的销售量统计图
def get_chart3(page):
    books = page_book = Book.query.paginate(page=page, per_page=8)
    x_data = []
    y_data = []
    for book in books:
        x_data.append(book.book_name)
        y_data.append(book.top)
    bar = (
        Bar(init_opts=opts.InitOpts(width='400px', height='400px', theme=ThemeType.LIGHT))
        .add_xaxis(x_data)  # 添加x轴数据
        .add_yaxis("销售量", y_data, )  # 添加男生数量序列，设置堆叠为'总量'  # 添加女生数量序列，同样设置堆叠为'总量'
        .set_global_opts(
            title_opts=opts.TitleOpts(title="分页销售量"),  # 设置图表标题
            yaxis_opts=opts.AxisOpts(name="图书"),  # 设置y轴名称
            datazoom_opts=[opts.DataZoomOpts(type_="slider", is_realtime=True)],
            toolbox_opts=opts.ToolboxOpts(  # 工具箱配置项
                is_show=True,  # 是否显示工具箱
                feature={
                    "saveAsImage": {},  # 保存为图片
                    "magicType": {  # 数据视图切换，保持默认配置即支持折线图和柱状图
                        "type": ["bar", "line"],
                        "title": {"line": "折线图", "bar": "柱状图"},
                    },
                },
            ),
        )
    )
    return bar


# 局部图-每个页面图书的售价分布图
def get_chart4(page):
    books = Book.query.paginate(page=page, per_page=8)
    prices = []
    y_data = []
    a, b, c, d, e, = 0, 0, 0, 0, 0
    x_data = ["0-30元", "31-60元", "61-100元", "101-200元", "201-500元"]
    for book in books:
        prices.append(float(book.price))
    for price in prices:
        if 0 <= price <= 30:
            a = a + 1
        elif 31 <= price <= 60:
            b = b + 1
        elif 61 <= price <= 100:
            c = c + 1
        elif 101 <= price <= 200:
            d = d + 1
        else:
            e = e + 1
    y_data.extend([a, b, c, d, e])
    pie = Pie(init_opts=opts.InitOpts(width='400px', height='400px', theme=ThemeType.LIGHT)).set_global_opts(
        title_opts=opts.TitleOpts(title="分页图书价格分布"),
        legend_opts=opts.LegendOpts(pos_left="70%", orient='vertical')  # 设置图表标题
    )
    pie.add(' ', [list(x) for x in zip(x_data, y_data)])
    return pie
